<template>
	<div>
		<!-- 面包屑导航区 -->
		<el-breadcrumb separator-class="el-icon-arrow-right">
		  <el-breadcrumb-item :to="{ path: '/home' }">首页</el-breadcrumb-item>
		  <el-breadcrumb-item>权限管理</el-breadcrumb-item>
		  <el-breadcrumb-item>角色列表</el-breadcrumb-item>
		</el-breadcrumb>
		
		<!-- 卡片视图区域 -->
		<el-card>
			<!-- 添加角色按钮 区域 -->
			<el-row>
				<el-col>
					<el-button type="primary" @click="addRoleVisible = true">添加角色</el-button>
				</el-col>
			</el-row>
			<!-- 角色列表 区域 -->
			<el-table :data="rolelist" border stripe>
				<!-- 展开列 -->
				<el-table-column type="expand">
					<template slot-scope="scope">
						<el-row v-for="(item1, i1) in scope.row.children" :key="item1.id"
						:class="['bdbottom', i1 === 0?'bdtop':'', 'vcenter']">
							<!-- 一级权限列 -->
							<el-col :span="5">
								<el-tag closable @close="removeRightById(scope.row, item1.id)">
									{{item1.authName}}
								</el-tag>
								<i class="el-icon-caret-right"></i>
							</el-col>
							<!-- 二、三级权限列 -->
							<el-col :span="19">
								<!-- 通过for循环嵌套渲染二级权限 -->
								<el-row v-for="(item2, i2) in item1.children" :key="item2.id"
								:class="[i2 === 0?'':'bdtop', 'vcenter']">
									<!-- 二级权限列 -->
									<el-col :span="6">
										<el-tag type="success"
										closable @close="removeRightById(scope.row, item2.id)">
											{{item2.authName}}
										</el-tag>
										<i class="el-icon-caret-right"></i>
									</el-col>
									<!-- 三级权限列 -->
									<el-col :span="18">
										<el-tag v-for="(item3, i3) in item2.children"
										:key="item3.id" type="warning" 
										closable @close="removeRightById(scope.row, item3.id)">
											{{item3.authName}}
										</el-tag>
									</el-col>
								</el-row>
							</el-col>
						</el-row>
						<!-- <pre>{{scope.row}}</pre> -->
					</template>
				</el-table-column>
				<!-- 索引列 -->
				<el-table-column type="index"></el-table-column>
				<!-- 数据列 -->
				<el-table-column label="角色名称" prop="roleName"></el-table-column>
				<el-table-column label="角色描述" prop="roleDesc"></el-table-column>
				<el-table-column label="操作" width="300px">
					<template slot-scope="scope">
						<el-button type="primary" icon="el-icon-edit" size="mini"
						@click="showEditDialog(scope.row.id)">编辑</el-button>
						<el-button type="danger" icon="el-icon-delete" size="mini"
						@click="removeRoleById(scope.row.id)">删除</el-button>
						<el-button type="warning" icon="el-icon-settings" size="mini"
						@click="showSetRightDialog(scope.row)">分配权限</el-button>
					</template>
				</el-table-column>
			</el-table>
		</el-card>
		
		<!-- 添加角色对话框 -->
		<el-dialog title="添加角色" :visible.sync="addRoleVisible" width="50%"
		@close="addDialogClosed">
			
		  <!-- 内容主体区域 -->
		  <!-- 表单-->
		  <el-form ref="addFormRef" :model="addRoleForm" label-width="100px"
		  :rules="addFormRules">
		    <el-form-item label="角色名称" prop="roleName">
		      <el-input v-model="addRoleForm.roleName"></el-input>
		    </el-form-item>
			<el-form-item label="角色描述" prop="roleDesc">
			  <el-input v-model="addRoleForm.roleDesc"></el-input>
			</el-form-item>
		  </el-form>
		  
		  <!-- 底部区域 -->
		  <span slot="footer" class="dialog-footer">
		    <el-button @click="addRoleVisible = false">取 消</el-button>
		    <el-button type="primary" @click="addRole">确 定</el-button>
		  </span>
		</el-dialog>
		
		<!-- 修改角色的对话框 -->
		<el-dialog title="修改角色信息" :visible.sync="editDialogVisible" width="50%"
		@close="editDialogclosed">
			
		  <!-- 内容主体区域 -->
		  <!-- 修改角色 表单-->
		  <el-form :model="editForm" :rules="editFormRules"
		  ref="editFormRef" label-width="120px">
			<el-form-item label="角色ID">
			  <el-input v-model="editForm.roleId" disabled></el-input>
			</el-form-item>
		    <el-form-item label="角色名称"  prop="roleName">
		      <el-input v-model="editForm.roleName"></el-input>
		    </el-form-item>
			<el-form-item label="角色描述" prop="roleDesc">
			  <el-input v-model="editForm.roleDesc"></el-input>
			</el-form-item>
		  </el-form>
		  
		  <!-- 底部区域 -->
		  <span slot="footer" class="dialog-footer">
		    <el-button @click="editDialogVisible = false">取 消</el-button>
		    <el-button type="primary" @click="editRoleInfo">确 定</el-button>
		  </span>
		</el-dialog>
		
		<!-- 分配权限对话框 -->
		<el-dialog
		  title="分配权限" :visible.sync="setRightDialogVisible" width="50%"
		  @close="setRightDialogClosed">
		  <!-- 树形控件 -->
		  <el-tree 
		  :data="rightslist" :props="treeProps"
		  show-checkbox node-key="id" default-expand-all
		  :default-checked-keys="defKeys"
		  ref="treeRef"></el-tree>
		  <span slot="footer" class="dialog-footer">
		    <el-button @click="setRightDialogVisible = false">取 消</el-button>
		    <el-button type="primary" @click="allotRights">确 定</el-button>
		  </span>
		</el-dialog>
		
		
	</div>
</template>

<script>
	export default {
		name: 'Rights',
		data(){
			return {
				rolelist: [],  //所有角色列表数据
				rightslist: [],  //保存请求到的权限数据
				addRoleVisible: false,  //添加角色对话框的显示隐藏控制标识
				editDialogVisible: false,  //修改角色对话框的显示隐藏控制标识
				setRightDialogVisible: false,  //分配权限对话框的显示隐藏控制标识
				addRoleForm: {  //添加角色的表单对象
					roleName: '',
					roleDesc: ''
				},
				editForm: {},  //编辑角色表单
				addFormRules: { //添加角色表单的验证规则对象
					roleName: [
						{
							required: true,
							message: '请输入角色名称',
							trigger: 'blur'
						}
					],
					roleDesc: [
						{
							required: true,
							message: '请输入角色描述',
							trigger: 'blur'
						}
					]
				},
				editFormRules: {  //修改角色表单的验证规则对象
					roleName: [
						{
							required: true,
							message: '请输入角色名称',
							trigger: 'blur'
						}
					],
					roleDesc: [
						{
							required: true,
							message: '请输入角色描述',
							trigger: 'blur'
						}
					]
				},
				treeProps: { //树形控件的props属性的绑定对象
					label:  'authName',
					children: 'children'
				},
				defKeys: [  //Tree组件的default-checked-keys属性的绑定对象
					
				],
				roleId: '',  //保存当前即将分配权限的角色的id
				
			}
		},
		created(){
			this.getRolesList()
		},
		methods: {
			//获取所有角色列表数据
			async getRolesList(){ 
				const {data: res} = await this.$http.get('roles')
				if(res.meta.status !== 200){
					return this.$message.error('获取角色列表失败！')
				}
				this.rolelist = res.data
				//console.log(this.rolelist)
			},
			//添加角色对话框的关闭事件的回调函数
			addDialogClosed(){
				this.$refs.addFormRef.resetFields()
			},
			//确认按钮click事件的回调
			addRole(){
				this.$refs.addFormRef.validate(async valid => {
					//console.log(valid)
					
					//当表单验证不通过时，直接退出
					if(!valid) return
					
					//当表单验证通过时，发起添加用户的网络请求
					const {data: res} = await this.$http.post('roles' , this.addRoleForm)
					
					if(res.meta.status !== 201){
						return this.$message.error('添加角色失败!')
					}
					
					this.$message.success('添加角色成功')
					
					//关闭对话框
					this.addRoleVisible = false
					
					//重新获取用户列表数据
					this.getRolesList()
					
				})								
			},	
			//编辑按钮的回调
			async showEditDialog(id){
				this.editDialogVisible = true
				
				//console.log(id)
				
				const {data: res} = await this.$http.get('roles/' + id)
				
				if(res.meta.status !== 200){
					return this.$message.error('查询角色信息失败!')
				}
				
				this.editForm = res.data
				
				//console.log (this.editForm)
			},
			//编辑角色对话框的close事件的回调
			editDialogclosed(){
				this.$refs.editFormRef.resetFields()
			},
			//编辑角色对话框的确认按钮的click事件的回调
			editRoleInfo(){
				this.$refs.editFormRef.validate(async valid => {
					//console.log(valid)
					if(!valid) return
					
					//发起网络请求
					//表单验证通过时，发起网络请求，让后台进行真正的修改
					const {data: res} = await this.$http.put('roles/'+this.editForm.roleId, {
						roleName: this.editForm.roleName,
						roleDesc: this.editForm.roleDesc
					})
					
					//console.log(res)
					
					if(res.meta.status !== 200){
						return this.$message.error('修改角色信息失败！')
					}
					
					//重新请求角色信息，刷新角色信息列表
					this.getRolesList()
					
					//提示修改成功
					this.$message.success('修改角色信息成功')
					
					//关闭对话框
					this.editDialogVisible = false
				})
			},
			//删除按钮的click事件的回调
			async removeRoleById(id){
				//console.log(id)
				
				//弹框询问是否删除用户数据
				const confirmResult = await this.$confirm('此操作将永久删除该角色, 是否继续?', '提示', {
				  confirmButtonText: '确定',
				  cancelButtonText: '取消',
				  type: 'warning'
				}).catch(err => err)
				
				if(confirmResult !== "confirm"){
					return this.$message.info('已取消删除')
				}
				
				//console.log('删除成功')
				//发起网络请求，让后台进行真正的删除
				const {data: res} = await this.$http.delete('roles/'+id)
				
				if(res.meta.status !== 200){
					return this.$message.error('删除角色失败！')
				}
				
				this.$message.success('删除角色成功')
				
				//刷新用户列表
				this.getRolesList()
			},
			//权限标签close事件的回调
			//根据id删除对应的权限
			async removeRightById(role, rightId){
				//弹框提示用户是否要删除
				const confirmResult = await this.$confirm('此操作将永久删除该权限, 是否继续?', '提示', {
				  confirmButtonText: '确定',
				  cancelButtonText: '取消',
				  type: 'warning'
				}).catch(err => err)
				
				if(confirmResult !== 'confirm'){
					return this.$message.info('取消了删除')
				}
				
				//console.log('确认了删除')
				
				//发起请求，让后台进行真正的删除
				const {data: res} = await this.$http.delete(`roles/${role.id}/rights/${rightId}`)
				
				if(res.meta.status !== 200){
					return this.$message.error('删除权限失败！')
				}
				
				this.$message.success('删除权限成功')
				
				//刷新权限列表
				//this.getRolesList()
				
				role.children = res.data
			},
			//分配权限按钮click事件的回调
			async showSetRightDialog(role){
				//将角色id保存到data中
				this.roleId = role.id
				
				//发起请求，获取权限数据
				const {data: res} = await this.$http.get('rights/tree')
				
				if(res.meta.status !== 200){
					return this.$message.error('获取权限数据失败!')
				}
				
				//将请求到的权限数据保存到data中
				this.rightslist = res.data
				//console.log(this.rightslist)
				
				//获取角色已有的所有三级权限的id
				this.getLeafKeys(role, this.defKeys)
				
				//显示对话框
				this.setRightDialogVisible = true
			},
			//递归函数
			//获取角色已有的三级权限id
			getLeafKeys(node, arr){
				//如果当前node节点不包含children属性，则是三级节点
				if(!node.children){
					return arr.push(node.id)
				}
				
				node.children.forEach(item => 
				this.getLeafKeys(item, arr))
			},
			//分配权限对话框close事件的回调
			//将defKefs数组清空
			setRightDialogClosed(){
				this.defKeys = []
			},
			//分配权限对话框 确认按钮 click事件的回调
			async allotRights(){
				//拿到勾选的权限的id
				const keys = [
					...this.$refs.treeRef.getCheckedKeys(),
					...this.$refs.treeRef.getHalfCheckedKeys()
				]
				//console.log(keys)
				
				const idStr = keys.join(',')
				
				//发起网络请求
				//让后台服务器进行保存
				const {data: res} = await this.$http.post(`roles/${this.roleId}/rights`,{
					rids: idStr
				})
				
				if(res.meta.status !== 200){
					return this.$message.error('分配权限失败！')
				}
				
				this.$message.success('分配权限成功！')
				
				//重新刷新整个角色列表表格
				this.getRolesList()
				
				//关闭分配权限对话框
				this.setRightDialogVisible = false
			},
			
		}
	}
</script>

<style lang="less" scoped="scoped">
	.el-tag {
		margin: 7px;
	}
	.bdtop {
		border-top: 1px solid #eee;
	}
	.bdbottom {
		border-bottom: 1px solid #eee;
	}
	.vcenter {
		display: flex;
		align-items: center;
	}
</style>
